package com.lf.mygpt.service;

import com.lf.mygpt.service.openai.OpenAiStreamListener;
import com.unfbx.chatgpt.OpenAiStreamClient;
import com.unfbx.chatgpt.entity.chat.ChatCompletion;
import com.unfbx.chatgpt.entity.chat.Message;
import com.unfbx.chatgpt.interceptor.OpenAILogger;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * @Author lifei
 * ChatGPT 相关处理
 */
@Service
public class GPTService {

    // openai 的 key
    @Value("${openai-key}")
    private String OPENAI_KEY;
    @Value("${api-host}")
    // 这里是 GPT 的代理服务器，如果你有服务器在国外，可以使用这个代理服务器，国内无法直接访问 ChatGPT
    // 我这里是买的易速云的海外服务器，1核2G专门搞了个Nginx做代理
    private String API_HOST;
    private static OpenAiStreamClient streamClient = null;
    private static final int TIMEOUT = 1000;

    @PostConstruct
    public void initStreamClient() {
        if (streamClient == null) {
            HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger());
            //！！！！千万别再生产或者测试环境打开BODY级别日志！！！！
            //！！！生产或者测试环境建议设置为这三种级别：NONE,BASIC,HEADERS,！！！
            httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
            OkHttpClient okHttpClient = new OkHttpClient
                    .Builder()
                    .addInterceptor(httpLoggingInterceptor)
                    .connectTimeout(30, TimeUnit.SECONDS)
                    .writeTimeout(30, TimeUnit.SECONDS)
                    .readTimeout(30, TimeUnit.SECONDS)
                    .build();
            streamClient = OpenAiStreamClient
                .builder()
                .apiKey(Collections.singletonList(OPENAI_KEY))
                .okHttpClient(okHttpClient)
                .apiHost(API_HOST)
                .build();
        }
    }

/**
 * 与 ChatGPT 聊天的代码实现
 * @param prompt 发送给 chatGPT 的内容
 * @return 返回 SseEmitter
 */
public SseEmitter chatCompletions(String prompt) {
    // 构造发送给GPT的Message
    Message message = Message.builder().role(Message.Role.USER).content(prompt).build();
    // 构造请求参数，具体参数含义可以查看 OpenAI官方文档
    ChatCompletion chatCompletion = ChatCompletion
            .builder()
            .model(ChatCompletion.Model.GPT_3_5_TURBO.getName())
            .temperature(0.2)
            .maxTokens(2048)
            .messages(Collections.singletonList(message))
            .stream(true)
            .build();

    // 设置事件监听器
    SseEmitter sseEmitter = new SseEmitter(0L);
    OpenAiStreamListener listener = new OpenAiStreamListener(sseEmitter);
    streamClient.streamChatCompletion(chatCompletion, listener);

    // 当所有内容返回完成后，触发 onCompletion 方法，可以在这里执行打印或保存聊天记录等逻辑
    sseEmitter.onCompletion(() -> {
        System.out.println(" == 完整的Prompt == ");
        System.out.println(prompt);
        System.out.println("\n");
        System.out.println(" == stream 流输出完成 == ");
        System.out.println(listener.getResult().toString());
    });
    return sseEmitter;
}



}
